﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

namespace ComLib.ComFun
{
	public class BitmapFunc
	{
		public unsafe static Bitmap Crop(Bitmap srcImage, Rectangle rec)
		{
			int width = rec.Width;
			int height = rec.Height;
			Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb);
			BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
			BitmapData bitmapData2 = srcImage.LockBits(rec, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
			int stride = bitmapData2.Stride;
			int stride2 = bitmapData.Stride;
			byte* ptr = (byte*)bitmapData.Scan0.ToPointer();
			byte* ptr2 = (byte*)bitmapData2.Scan0.ToPointer();
			for (int i = 0; i < height; i++)
			{
				memcpy(ptr, ptr2, stride2);
				ptr += stride2;
				ptr2 += stride;
			}
			bitmap.UnlockBits(bitmapData);
			srcImage.UnlockBits(bitmapData2);
			return bitmap;
		}

		public static Bitmap BmpClone(Bitmap img)
		{
			if (img == null)
			{
				return null;
			}
			return Clone(img);
		}

		public static Bitmap Clone(Bitmap source, PixelFormat format)
		{
			if (source == null)
			{
				return null;
			}
			if (source.PixelFormat == format)
			{
				return Clone(source);
			}
			int width = source.Width;
			int height = source.Height;
			Bitmap bitmap = new Bitmap(width, height, format);
			using (Graphics graphics = Graphics.FromImage(bitmap))
			{
				graphics.DrawImage(source, 0, 0, width, height);
				graphics.Dispose();
				return bitmap;
			}
		}

		public static Bitmap Clone(Bitmap source)
		{
			BitmapData bitmapData = source.LockBits(new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadOnly, source.PixelFormat);
			Bitmap bitmap = null;
			try
			{
				bitmap = Clone(bitmapData);
			}
			catch
			{
				bitmap = null;
			}
			finally
			{
				source.UnlockBits(bitmapData);
			}
			if (bitmap == null)
			{
				return null;
			}
			if (source.PixelFormat == PixelFormat.Format1bppIndexed || source.PixelFormat == PixelFormat.Format4bppIndexed || source.PixelFormat == PixelFormat.Format8bppIndexed || source.PixelFormat == PixelFormat.Indexed)
			{
				ColorPalette palette = source.Palette;
				ColorPalette palette2 = bitmap.Palette;
				int num = palette.Entries.Length;
				for (int i = 0; i < num; i++)
				{
					palette2.Entries[i] = palette.Entries[i];
				}
				bitmap.Palette = palette2;
			}
			return bitmap;
		}

		public static Bitmap Clone(BitmapData sourceData)
		{
			int width;
			int height;
			try
			{
				width = sourceData.Width;
				height = sourceData.Height;
			}
			catch
			{
				return null;
			}
			Bitmap bitmap = new Bitmap(width, height, sourceData.PixelFormat);
			BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
			try
			{
				CopyUnmanagedMemory(bitmapData.Scan0, sourceData.Scan0, height * sourceData.Stride);
				return bitmap;
			}
			catch
			{
				return bitmap;
			}
			finally
			{
				bitmap.UnlockBits(bitmapData);
			}
		}

		[DllImport("ntdll.dll", CallingConvention = CallingConvention.Cdecl)]		public unsafe static extern byte* memcpy(byte* dst, byte* src, int count);

		public unsafe static IntPtr CopyUnmanagedMemory(IntPtr dst, IntPtr src, int count)
		{
			CopyUnmanagedMemory((byte*)dst.ToPointer(), (byte*)src.ToPointer(), count);
			return dst;
		}

		public unsafe static byte* CopyUnmanagedMemory(byte* dst, byte* src, int count)
		{
			return memcpy(dst, src, count);
		}
	}
}
